/*
 Copyright (c) Whitemice Consulting, 2007, 2008, 2009
 Adam Tauno Williams <awilliam@whitemice.org>
 License: MIT/X11

 Permission is hereby granted, free of charge, to any person obtaining a copy
 of this software and associated documentation files (the "Software"), to deal
 in the Software without restriction, including without limitation the rights
 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 copies of the Software, and to permit persons to whom the Software is
 furnished to do so, subject to the following conditions:

 The above copyright notice and this permission notice shall be included in
 all copies or substantial portions of the Software.
 
 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 THE SOFTWARE.
*/
using System;
using Gtk;
using Whitemice.ZOGI;
using Whitemice.ZOGI.GtkWidgets;
using Whitemice.ZOGI.GtkFolios;

namespace Whitemice.Consonance
{
  /// <summary>
  /// With to display a Project folio and host appropriate actions
  /// </summary>
	public partial class ProjectWindow : EntityWindow
	{
		protected Whitemice.ZOGI.Project							project;
		protected ProjectFolio	                      folio;
		protected ContactSearchDialog                 contactSearchDialog;
		protected EnterpriseSearchDialog	            enterpriseSearchDialog;
		
		public ProjectWindow(Whitemice.ZOGI.Project _project) : 
				base(Gtk.WindowType.Toplevel)
		{
			this.Build();
		  contactSearchDialog = null;
		  enterpriseSearchDialog = null;
			folio = new Whitemice.ZOGI.GtkFolios.ProjectFolio();
			folioarea.Child = folio;
      Fill(_project);
			folio.ContactTab.OnContactEdit += new EntityEventHandler(ContactEdit);
			folio.ContactTab.OnContactRemove += new EntityEventHandler(ContactRemove);
			folio.ContactTab.OnContactUnassign += new EntityEventHandler(ContactUnassign);
			folio.EnterpriseTab.OnEnterpriseEdit += new EntityEventHandler(EnterpriseEdit);
			folio.EnterpriseTab.OnEnterpriseRemove += new EntityEventHandler(EnterpriseRemove);
			folio.EnterpriseTab.OnEnterpriseUnassign += new EntityEventHandler(EnterpriseUnassign);
			folio.TaskTab.PopupEnabled = true;
			folio.TaskTab.OnTaskEvent += new EntityEventHandler(EntityEvent);
			folio.OnTabThaw += new EventHandler(ThawOneLevel);
			folio.LinksTab.OnEntityPresent += new EntityEventHandler(Present);
			folio.NoteTab.OnEntityPresent += new EntityEventHandler(Present);
			folio.NoteTab.OnNoteDelete += new EntityEventHandler(DeleteNote);
		} // end ctor

    public override Entity Current { get { return project; } }

    protected override void Fill(Entity entity)
    {
      this.EntityNameCheck(entity, typeof(Whitemice.ZOGI.Project));
      project = (entity as Whitemice.ZOGI.Project);
      FreezeToDepth(1);
      Registry.RegisterForNotification(project, this);
      folio.Fill(Current);
      SetTitle();
      if (project.CanModify)
      {
      } else
        {
        }    
    }

    protected void SetTitle()
    {
      if (project.ObjectId < 1)
        this.Title = "New Project";
        else this.Title = "Project#" + project.ObjectId.ToString() + ": " +
                project.Name;
    }
		
    public override void ProcessEvent(Whitemice.ZOGI.ServerEvent _event)
    {
      switch(_event.Event)
      {
        case ServerEventType.Update:
          Fill();
          break;
        case ServerEventType.SubordinateChange:
          folio.EnterpriseTab.Fill(project);
          folio.ContactTab.Fill(project);
          folio.TaskTab.Fill(project);
          folio.NoteTab.Fill(project);
          break;
      } // end event-switch 
    } // end ProcessEvent
		
		protected override bool Take()
		{
			return folio.Take(project);
		}

    protected override void SaveCallback(Entity entity, Exception exception, object context)
    {
      if (exception == null)
      {
        this.ZLOG(string.Format("SaveCallback(objectId#{0})", entity.ObjectId));
        folio.Fill(entity);
      } else
        {
          new MessageBox(exception);
        }
      Thaw();
    }

		protected virtual void OnApplyClicked(
			object sender, 
			System.EventArgs args)
		{
			Save(project, false);
		} // end OnApplyClicked

		protected virtual void OnCancelClicked(
			object sender, 
			System.EventArgs args)
		{
			Unregister(project, true);
		} // end OnCancelClicked
		
		protected virtual void OnOkClicked(
			object sender, 
			System.EventArgs args)
		{
      Save(project, true);
		} // end OnOkClicked
		
		protected virtual void EntityEvent(
			Entity _entity, 
			object _context,
			Exception _exception)
		{
			string context;
			
			context = (_context as string);
			switch(_entity.EntityName)
			{
				case "Task":
					switch(context)
					{
						case "edit":
							if (!(GUI.RaiseWindow(_entity)))
									new TaskWindow((_entity as Task));
							break;
						case "accept":
							new TaskActionDialog(
								this,
								(_entity as Task),
								TaskAction.Accept);
							break;
						case "comment":
							new TaskActionDialog(
								this,
								(_entity as Task),
								TaskAction.Comment);							
							break;
						case "reject":
							new TaskActionDialog(
								this,
								(_entity as Task),
								TaskAction.Reject);							
							break;
						case "done":
							new TaskActionDialog(
								this,
								(_entity as Task),
								TaskAction.Done);							
							break;
						case "archive":
							new TaskActionDialog(
								this,
								(_entity as Task),
								TaskAction.Archive);							
							break;
						case "activate":
							new TaskActionDialog(
								this,
								(_entity as Task),
								TaskAction.Activate);							
							break;							
					}
					break;
			}
		} /* end EntityEvent */
		
		protected virtual void ContactEdit(
		  Entity _entity,
			object _context, 
			Exception _ex)
		{
		  if (_entity != null)
		    if (!(GUI.RaiseWindow(_entity)))
				  new ContactWindow((_entity as Contact)); 		
		} /* end ContactEdit */

		protected virtual void ContactRemove(
		  Entity _entity,
			object _context, 
			Exception _ex)
		{
      /*
			if (GUI.RaiseWindow(_entity))
			{
				new MessageBox("Object#" + _entity.ObjectId.ToString() + " is currently in use.");
			} else
				{
					if (_entity.CanModify)
					{
						// User has modification privileges 
						if (ZOGIApplication.Server.Remove(_entity))
						{
							// Delete was successful 
							project.Unassign(_entity);
							new MessageBox("Deletion successful.");
						} else 
							{
								// Delete failed 
								new MessageBox("Deletion failed");
							}
					} else 
						{
							// Insufficient privileges to delete object 
							new MessageBox("You lack sufficient privilages to perform the requested action");
						}
				} // End else-object-is-available
      */
		} // end ContactRemove */

		protected virtual void ContactUnassign(
		  Entity _entity,
			object _context, 
			Exception _ex)
		{
		  if (project.CanModify)
		  {
		    project.Unassign(_entity);
		    folio.ContactTab.Fill(project);
		  } else new MessageBox("You lack sufficient privilages to perform the requested action");		
		} // end ContactUnassign

		protected virtual void EnterpriseEdit(
		  Entity _entity,
			object _context, 
			Exception _ex)
		{
		  if (_entity != null)
		    if (!(GUI.RaiseWindow(_entity)))
				  new EnterpriseWindow((_entity as Enterprise)); 
		} /* end EnterpriseEdit */

		protected virtual void EnterpriseRemove(
		  Entity _entity,
			object _context, 
			Exception _ex)
		{
      new MessageBox("Not yet implmented");
      /*
			if (GUI.RaiseWindow(_entity))
			{
				// Object is being viewed, present the window and notify user 
				new MessageBox("Object#" + _entity.ObjectId.ToString() + " is currently in use.");
			} else
				{
					if (_entity.CanModify)
					{
						// User has modification privileges 
						if (ZOGIApplication.Server.Remove(_entity))
						{
							// Delete was successful 
							project.Unassign(_entity);
							new MessageBox("Deletion successful.");
						} else 
							{
								// Delete failed 
								new MessageBox("Deletion failed");
							}
					} else 
						{
							// Insufficient privileges to delete object 
							new MessageBox("You lack sufficient privilages to perform the requested action");
						}
				} // End else-object-is-available
		  */
		} /* end EnterpriseRemove */

		protected virtual void EnterpriseUnassign(
		  Entity _entity,
			object _context, 
			Exception _ex)
		{ 
		  if (project.CanModify)
		  {
		    project.Unassign(_entity);
		    folio.EnterpriseTab.Fill(project);
		  } else new MessageBox("You lack sufficient privilages to perform the requested action");
		} /* end EnterpriseUnassign */

		protected virtual void OnNewTaskActionActivated (object sender, System.EventArgs e)
		{
		  //new TaskWindow(project.ObjectId, project.Name);
		} // end OnNewTaskActionActivated

		protected virtual void OnAddNotationActionActivated (object sender, System.EventArgs e)
		{
      if (project.CanModify)        
		    new NoteDialog(project);
      else new MessageBox("You lack sufficient privileges to add notations to this project.",
                          MessageType.Warning);
		} // end OnAddNotationActionActivated

		protected virtual void OnDeleteEvent (object o, Gtk.DeleteEventArgs args)
		{
		  Unregister(project, true);
		}// end OnDestroyEvent
		
		protected virtual void DeleteNote(Entity entity, object context, Exception exception)
		{
		  if ((exception == null) && (entity != null))
		  {
		    bool result;
		    if (entity is Whitemice.ZOGI.Note)
		    {
		      result = false;
		      try
		      {
		        //Registry.Server.Remove(entity);
		        result = true;
		      } catch (Exception ex)
		        {
		          new MessageBox(ex);
		        }
		        finally
		        {
		          if (result)
		            folio.Fill(project);
		        }
		    } // end entity-is-note
		  } // end entity-is-ok
		} // end DeleteNote

		protected virtual void OnAssignContactActionActivated (object sender, System.EventArgs e)
		{
		  if(project.CanModify)
		  {
			  if (contactSearchDialog == null)
		  	{
			  	contactSearchDialog = new ContactSearchDialog(
			  		ZOGIUtility.GetWindow(this), 
			  		project.ObjectId,
					  "Assign contact to " + project.Name);
			    contactSearchDialog.SetContactId += 
					  new ContactSearchDialog.SetContactIdHandler(ContactAssign);
					contactSearchDialog.Modal = false;
				}
				contactSearchDialog.Present();
		  } else new MessageBox("You lack sufficient privileges to assign contacts to this project.",
                            DialogFlags.Modal | DialogFlags.DestroyWithParent,
                            MessageType.Warning,
                            ButtonsType.Close);
		} // end OnAssignContactActionActivated
		
		public virtual void ContactAssign(int contactId)
		{
      //TODO: Make Contact Assign Asyncronous
      Entity entity;
      
      this.ZLOG("Project#{0} contact assign (Contact#{1})", 
                project.ObjectId,
                contactId);
      if (contactId > 0)
      {
        entity = Server.Connection.Get(contactId, 65535, true);
        if (entity == null)
        {
        } else if (entity is Whitemice.ZOGI.Contact)
          {
            project.Assign(entity);
            folio.ContactTab.Fill(project);
          } else
            {
            }
      } else new MessageBox("Contact must be committed before it can be assigned", 
                            DialogFlags.Modal, 
                            MessageType.Warning, 
                            ButtonsType.Close);
		} // end ContactAssign

		protected virtual void OnAssignEnterpriseActionActivated (object sender, System.EventArgs e)
		{
		  if(project.CanModify)
		  {
			  if (enterpriseSearchDialog == null)
		  	{
			  	enterpriseSearchDialog = new EnterpriseSearchDialog(
			  		ZOGIUtility.GetWindow(this), 
			  		project.ObjectId,
					  "Assign enterprise to " + project.Name);
			    enterpriseSearchDialog.SetEnterpriseId += 
					  new EnterpriseSearchDialog.SetEnterpriseIdHandler(EnterpriseAssign);
				}
				enterpriseSearchDialog.Present();
		  } else new MessageBox("You lack sufficient privileges to assign enterprises to this project.",
                            DialogFlags.Modal | DialogFlags.DestroyWithParent,
                            MessageType.Warning,
                            ButtonsType.Close);	
		} // end OnAssignEnterpriseActionActivated
		
		public virtual void EnterpriseAssign(int enterpriseId)
		{
      //TODO: Make Asyncronous
      Entity entity;
      
      this.ZLOG("Project#{0} enterprise assign (Enterprise#{1})", 
                project.ObjectId,
                enterpriseId);
      if (enterpriseId > 0)
      {
        entity = Server.Connection.Get(enterpriseId, 65535, true);
        if (entity == null)
        {
        } else if (entity is Whitemice.ZOGI.Enterprise)
          {
            project.Assign(entity);
            folio.ContactTab.Fill(project);
          } else
            {
            }
      } else new MessageBox("Enterprise must be committed before it can be assigned", 
                            DialogFlags.Modal, 
                            MessageType.Warning, 
                            ButtonsType.Close);
    } // end EnterpriseAssign

		protected virtual void OnRefreshActionActivated (object sender, System.EventArgs e)
		{
      folio.Fill(project);
		}
	} // end ProjectWindow
} // end namespace
